import React, {ReactNode, RefObject} from "react";
import BasePureComponent from "@/components/common/BasePureComponent";
import {
  FullscreenOutlined,
  SyncOutlined
} from "@ant-design/icons";
import {Empty} from "antd";
import A from "@/components/A";
import './index.scss'
import StateImglazy from "@/components/SateImg/StateImglazy";
import Scaling from "@/components/SateImg/Scaling";

interface ImgProps {
  para?: any;
  src?: string;
  scrollDom?: any; // 用于懒加载
  markingClass?: string;
  className?: string;
  style?: object; // 暴露style
  cover?: boolean;
  fullscreenUrl?: string;
  allowFullscreen?: boolean;
  allowMagnifier?: boolean;
  scaling?: boolean;
  tagDesc?: string | ReactNode;
  magnifierDestroyOnClose?: boolean;
  onClickFullscreen?: (fullscreenUrl?: string) => void;
  onClick?: (para?: any) => void;
  onImgLoad?: (width?: number, height?: number) => void;
  customizeOperateModule?: ReactNode;
  onRef?: (ref: ReactNode) => void;
}

interface ImgState {
  loading: boolean;
  error: boolean;
  coverNoHeight: boolean;
  imgWidth: number;
  imgHeight: number;
}

enum RENDER_STATUS {
  IMAGE,
  LOADING,
  ERROR,
  EMPTY
}

let g_id = 0;

function PictureOutlined() {
  return null;
}

class StateImg extends BasePureComponent<ImgProps, ImgState> {
  private contentRef: RefObject<any>;
  private observe: any;
  private magnifier?: any;
  private id: number;
  private scalingRef: React.RefObject<any>;

  constructor(props: ImgProps) {
    super(props);
    this.contentRef = React.createRef();
    this.scalingRef = React.createRef();
    this.id = ++g_id;
    this.state = {
      loading: true,
      error: false,
      coverNoHeight: false,
      imgWidth: 0,
      imgHeight: 0
    };
    this.handleClick = this.handleClick.bind(this);
    this.imageLoad = this.imageLoad.bind(this);
    this.boundScroll = this.boundScroll.bind(this);
  }

  imageLoad() {
    const self = this;
    if (!self.props.src) {
      return;
    }
    self.setState({
      loading: true,
      error: false
    });
    const img = new Image();
    img.onload = () => {
      self.setState({
        loading: false,
        error: false,
        imgWidth: img.width,
        imgHeight: img.height
      });
      if (this.props.onImgLoad) {
        this.props.onImgLoad(img.width, img.height);
      }
    };
    img.onerror = () => {
      self.setState({
        loading: false,
        error: true
      });
    };

    img.src = self.props.src;

    if (self.contentRef.current && self.contentRef.current.offsetHeight < 90) {
      self.setState({
        coverNoHeight: true // 设定一个最小高度
      });
    }
  }

  boundScroll() {
    this.unboundScroll();
    this.observe = StateImglazy.bound(
      this.props.scrollDom.current,
      this.contentRef.current,
      this.imageLoad
    );
  }

  unboundScroll() {
    if (this.observe) {
      StateImglazy.unbound(this.observe, this.contentRef.current);
      this.observe = null;
    }
  }

  componentDidUpdate(prevProps: ImgProps, prevState: ImgState) {
    if (this.props.src !== prevProps.src) {
      this.props.scaling && this.scalingRef.current.reset();
      if (this.props.scrollDom) {
        this.boundScroll();
      } else {
        this.imageLoad();
      }
    }
  }

  componentDidMount() {
    this.props.onRef && this.props.onRef(this);
    if (this.props.scrollDom) {
      this.boundScroll();
    } else {
      this.imageLoad();
    }
  }

  componentWillUnmount() {
    super.componentWillUnmount();
    if (this.magnifier) {
      this.magnifier.stopMagnifier();
      this.magnifier = undefined;
    }
    this.unboundScroll();
  }

  handleClick(e: any) {
    if (e.target.nodeName.toLowerCase() !== "div") {
      return;
    }

    if (this.props.onClick) {
      this.props.onClick(this.props.para);
    }
  }

  scaleReset = () => {
    this.scalingRef.current.reset();
  };

  render() {
    const divProp: any = {};

    if (this.props.onClick) {
      divProp.onClick = this.handleClick;
    }

    let coverClassName = (this.props.className || "") + " stateImg ";
    if (this.props.markingClass) {
      coverClassName += this.props.markingClass;
    }

    if (!this.props.src || this.state.loading || this.state.error) {
      coverClassName += " " + "noImg";
    }

    let renderStatus: RENDER_STATUS;
    let allowFullscreen = this.props.allowFullscreen;
    const onClickFullscreen = this.props.onClickFullscreen;
    const customizeOperateModule = this.props.customizeOperateModule;
    const scaling = this.props.scaling;
    const allowMagnifier = this.props.allowMagnifier;
    if (this.props.src) {
      if (!onClickFullscreen && this.props.src.length > 1024) {
        allowFullscreen = false;
      }
      if (this.state.error) {
        renderStatus = RENDER_STATUS.ERROR;
      } else if (this.state.loading) {
        renderStatus = RENDER_STATUS.LOADING;
      } else {
        renderStatus = RENDER_STATUS.IMAGE;
      }
    } else {
      renderStatus = RENDER_STATUS.EMPTY;
    }

    if (renderStatus !== RENDER_STATUS.IMAGE && this.state.coverNoHeight) {
      coverClassName += " defaultHeight";
    }

    return (
      <div
        ref={this.contentRef}
        {...divProp}
        className={scaling ? `scaling ${coverClassName}` : coverClassName}
        style={this.props.style}
      >
        {!scaling ? (
          renderStatus === RENDER_STATUS.IMAGE &&
          allowMagnifier && (
            <div>2121</div>
            /*<Magnifier
              id={this.id}
              contentRef={this.contentRef}
              realWidth={this.state.imgWidth}
              realHeight={this.state.imgHeight}
              url={this.props.src}
              destroyOnClose={this.props.magnifierDestroyOnClose}
            />*/
          )
        ) : (
          <Scaling url={this.props.src} ref={this.scalingRef}/>
        )}

        {this.props.src && this.props.src.length < 2048 && (
          <input type="hidden" value={this.props.src || ""}/>
        )}

        {renderStatus === RENDER_STATUS.EMPTY && <Empty/>}

        {renderStatus === RENDER_STATUS.LOADING && (
          <div className="loading">
            <div className="content-icon">
              <SyncOutlined spin/>
              <div>图片加载中</div>
            </div>
          </div>
        )}

        {renderStatus === RENDER_STATUS.ERROR && (
          <div className="error">
            <div className="content-icon">
              <PictureOutlined/>
              <div>图片加载失败</div>
            </div>
          </div>
        )}

        {renderStatus === RENDER_STATUS.IMAGE && !scaling && (
          <img alt="" src={this.props.src} className={this.props.cover ? "cover" : "original"}/>
        )}

        {renderStatus === RENDER_STATUS.IMAGE &&
        allowFullscreen &&
        (onClickFullscreen ? (
          <A para={this.props.fullscreenUrl || this.props.src} onClick={onClickFullscreen}>
            <FullscreenOutlined/>
          </A>
        ) : (
          <a
            // href={this.props.fullscreenUrl || this.props.src}
            href={`/waterMark?url=${encodeURIComponent(this.props.fullscreenUrl || this.props.src || "")}`}
            target="_blank"
          >
            <FullscreenOutlined/>
          </a>
        ))}

        {renderStatus === RENDER_STATUS.IMAGE && scaling && (
          <i className={`scaling-reset ${!allowFullscreen && "right"}`} onClick={() => {
            this.scaleReset();
          }}>
            <SyncOutlined/>
          </i>
        )}

        {renderStatus === RENDER_STATUS.IMAGE && customizeOperateModule}

        {this.props.tagDesc && (<div className="tagdesc">{this.props.tagDesc}</div>)}

        {renderStatus === RENDER_STATUS.IMAGE && allowMagnifier && (
          <div className="innerMagnifier"/>
        )}
      </div>
    )
  }
}

export default StateImg;
